const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
const { generateOrderNumber } = require('../utils/orderUtils');
const { ApiError } = require('../utils/apiError');

/**
 * 获取入库单列表
 */
exports.getStockInOrders = async (req, res, next) => {
  try {
    const {
      page = 1,
      pageSize = 20,
      orderNumber,
      orderType,
      supplierId,
      warehouseId,
      status,
      startDate,
      endDate
    } = req.query;

    const where = {};
    
    // 构建查询条件
    if (orderNumber) {
      where.orderNumber = { contains: orderNumber };
    }
    
    if (orderType) {
      where.orderType = parseInt(orderType);
    }
    
    if (supplierId) {
      where.supplierId = parseInt(supplierId);
    }
    
    if (warehouseId) {
      where.warehouseId = parseInt(warehouseId);
    }
    
    if (status !== undefined) {
      where.status = parseInt(status);
    }
    
    if (startDate && endDate) {
      where.orderDate = {
        gte: new Date(startDate),
        lte: new Date(endDate)
      };
    } else if (startDate) {
      where.orderDate = {
        gte: new Date(startDate)
      };
    } else if (endDate) {
      where.orderDate = {
        lte: new Date(endDate)
      };
    }
    
    // 计算分页参数
    const skip = (parseInt(page) - 1) * parseInt(pageSize);
    const take = parseInt(pageSize);
    
    // 查询入库单及相关数据
    const [stockInOrders, total] = await Promise.all([
      prisma.stockInOrder.findMany({
        where,
        skip,
        take,
        orderBy: { orderDate: 'desc' },
        include: {
          warehouse: { select: { id: true, name: true } },
          supplier: { select: { id: true, name: true } },
          operator: { select: { id: true, name: true } }
        }
      }),
      prisma.stockInOrder.count({ where })
    ]);
    
    res.json({
      success: true,
      data: {
        items: stockInOrders,
        total,
        page: parseInt(page),
        pageSize: parseInt(pageSize),
        totalPages: Math.ceil(total / parseInt(pageSize))
      }
    });
  } catch (error) {
    next(error);
  }
};

/**
 * 获取入库单详情
 */
exports.getStockInOrderById = async (req, res, next) => {
  try {
    const { id } = req.params;
    
    const stockInOrder = await prisma.stockInOrder.findUnique({
      where: { id: parseInt(id) },
      include: {
        warehouse: true,
        supplier: true,
        operator: { select: { id: true, name: true } },
        items: {
          include: {
            product: { select: { id: true, name: true, sku: true, stockUnit: true } }
          }
        }
      }
    });
    
    if (!stockInOrder) {
      throw new ApiError(404, '入库单不存在');
    }
    
    res.json({
      success: true,
      data: stockInOrder
    });
  } catch (error) {
    next(error);
  }
};

/**
 * 创建入库单
 */
exports.createStockInOrder = async (req, res, next) => {
  try {
    const {
      orderType,
      warehouseId,
      supplierId,
      orderDate,
      remarks,
      items
    } = req.body;
    
    // 验证必填参数
    if (!orderType) {
      throw new ApiError(400, '入库类型不能为空');
    }
    
    if (!warehouseId) {
      throw new ApiError(400, '仓库不能为空');
    }
    
    if (!orderDate) {
      throw new ApiError(400, '入库日期不能为空');
    }
    
    if (!items || !Array.isArray(items) || items.length === 0) {
      throw new ApiError(400, '入库商品不能为空');
    }
    
    // 检查仓库是否存在
    const warehouse = await prisma.warehouse.findUnique({
      where: { id: parseInt(warehouseId) }
    });
    
    if (!warehouse) {
      throw new ApiError(404, '仓库不存在');
    }
    
    // 如果是采购入库，检查供应商是否存在
    if (orderType === 1 && supplierId) {
      const supplier = await prisma.supplier.findUnique({
        where: { id: parseInt(supplierId) }
      });
      
      if (!supplier) {
        throw new ApiError(404, '供应商不存在');
      }
    }
    
    // 生成入库单号
    const orderNumber = await generateOrderNumber('RK');
    
    // 计算总金额
    const totalAmount = items.reduce((sum, item) => {
      return sum + (parseFloat(item.quantity) * parseFloat(item.costPrice || 0));
    }, 0);
    
    // 创建入库单
    const stockInOrder = await prisma.$transaction(async (prisma) => {
      // 创建入库单主表
      const newStockInOrder = await prisma.stockInOrder.create({
        data: {
          orderNumber,
          orderType: parseInt(orderType),
          warehouseId: parseInt(warehouseId),
          supplierId: supplierId ? parseInt(supplierId) : null,
          orderDate: new Date(orderDate),
          status: 0, // 草稿状态
          totalAmount,
          remarks,
          operatorId: req.user.id
        }
      });
      
      // 创建入库单明细
      const itemsData = items.map(item => ({
        stockInId: newStockInOrder.id,
        productId: parseInt(item.productId),
        quantity: parseFloat(item.quantity),
        unit: item.unit,
        costPrice: parseFloat(item.costPrice || 0),
        totalPrice: parseFloat(item.quantity) * parseFloat(item.costPrice || 0),
        batchNumber: item.batchNumber || null,
        productionDate: item.productionDate ? new Date(item.productionDate) : null,
        expiryDate: item.expiryDate ? new Date(item.expiryDate) : null,
        remarks: item.remarks
      }));
      
      await prisma.stockInItem.createMany({
        data: itemsData
      });
      
      // 重新查询包含明细的入库单
      return await prisma.stockInOrder.findUnique({
        where: { id: newStockInOrder.id },
        include: {
          warehouse: true,
          supplier: true,
          operator: { select: { id: true, name: true } },
          items: true
        }
      });
    });
    
    res.status(201).json({
      success: true,
      data: stockInOrder,
      message: '入库单创建成功'
    });
  } catch (error) {
    next(error);
  }
};

/**
 * 更新入库单
 */
exports.updateStockInOrder = async (req, res, next) => {
  try {
    const { id } = req.params;
    const {
      orderType,
      warehouseId,
      supplierId,
      orderDate,
      remarks,
      items
    } = req.body;
    
    // 查询入库单
    const stockInOrder = await prisma.stockInOrder.findUnique({
      where: { id: parseInt(id) },
      include: { items: true }
    });
    
    if (!stockInOrder) {
      throw new ApiError(404, '入库单不存在');
    }
    
    // 只有草稿状态的入库单可以更新
    if (stockInOrder.status !== 0) {
      throw new ApiError(400, '只有草稿状态的入库单可以更新');
    }
    
    // 验证必填参数
    if (!orderType) {
      throw new ApiError(400, '入库类型不能为空');
    }
    
    if (!warehouseId) {
      throw new ApiError(400, '仓库不能为空');
    }
    
    if (!orderDate) {
      throw new ApiError(400, '入库日期不能为空');
    }
    
    if (!items || !Array.isArray(items) || items.length === 0) {
      throw new ApiError(400, '入库商品不能为空');
    }
    
    // 检查仓库是否存在
    const warehouse = await prisma.warehouse.findUnique({
      where: { id: parseInt(warehouseId) }
    });
    
    if (!warehouse) {
      throw new ApiError(404, '仓库不存在');
    }
    
    // 如果是采购入库，检查供应商是否存在
    if (orderType === 1 && supplierId) {
      const supplier = await prisma.supplier.findUnique({
        where: { id: parseInt(supplierId) }
      });
      
      if (!supplier) {
        throw new ApiError(404, '供应商不存在');
      }
    }
    
    // 计算总金额
    const totalAmount = items.reduce((sum, item) => {
      return sum + (parseFloat(item.quantity) * parseFloat(item.costPrice || 0));
    }, 0);
    
    // 更新入库单
    const updatedStockInOrder = await prisma.$transaction(async (prisma) => {
      // 删除原有明细
      await prisma.stockInItem.deleteMany({
        where: { stockInId: parseInt(id) }
      });
      
      // 更新入库单主表
      await prisma.stockInOrder.update({
        where: { id: parseInt(id) },
        data: {
          orderType: parseInt(orderType),
          warehouseId: parseInt(warehouseId),
          supplierId: supplierId ? parseInt(supplierId) : null,
          orderDate: new Date(orderDate),
          totalAmount,
          remarks
        }
      });
      
      // 创建新的入库单明细
      const itemsData = items.map(item => ({
        stockInId: parseInt(id),
        productId: parseInt(item.productId),
        quantity: parseFloat(item.quantity),
        unit: item.unit,
        costPrice: parseFloat(item.costPrice || 0),
        totalPrice: parseFloat(item.quantity) * parseFloat(item.costPrice || 0),
        batchNumber: item.batchNumber || null,
        productionDate: item.productionDate ? new Date(item.productionDate) : null,
        expiryDate: item.expiryDate ? new Date(item.expiryDate) : null,
        remarks: item.remarks
      }));
      
      await prisma.stockInItem.createMany({
        data: itemsData
      });
      
      // 重新查询包含明细的入库单
      return await prisma.stockInOrder.findUnique({
        where: { id: parseInt(id) },
        include: {
          warehouse: true,
          supplier: true,
          operator: { select: { id: true, name: true } },
          items: true
        }
      });
    });
    
    res.json({
      success: true,
      data: updatedStockInOrder,
      message: '入库单更新成功'
    });
  } catch (error) {
    next(error);
  }
};

/**
 * 删除入库单
 */
exports.deleteStockInOrder = async (req, res, next) => {
  try {
    const { id } = req.params;
    
    // 查询入库单
    const stockInOrder = await prisma.stockInOrder.findUnique({
      where: { id: parseInt(id) }
    });
    
    if (!stockInOrder) {
      throw new ApiError(404, '入库单不存在');
    }
    
    // 只有草稿状态的入库单可以删除
    if (stockInOrder.status !== 0) {
      throw new ApiError(400, '只有草稿状态的入库单可以删除');
    }
    
    // 删除入库单
    await prisma.$transaction(async (prisma) => {
      // 删除明细
      await prisma.stockInItem.deleteMany({
        where: { stockInId: parseInt(id) }
      });
      
      // 删除主表
      await prisma.stockInOrder.delete({
        where: { id: parseInt(id) }
      });
    });
    
    res.json({
      success: true,
      message: '入库单删除成功'
    });
  } catch (error) {
    next(error);
  }
};

/**
 * 确认入库单
 */
exports.confirmStockInOrder = async (req, res, next) => {
  try {
    const { id } = req.params;
    
    // 查询入库单及明细
    const stockInOrder = await prisma.stockInOrder.findUnique({
      where: { id: parseInt(id) },
      include: { items: true }
    });
    
    if (!stockInOrder) {
      throw new ApiError(404, '入库单不存在');
    }
    
    // 只有草稿状态的入库单可以确认
    if (stockInOrder.status !== 0) {
      throw new ApiError(400, '只有草稿状态的入库单可以确认');
    }
    
    // 检查入库单明细
    if (!stockInOrder.items || stockInOrder.items.length === 0) {
      throw new ApiError(400, '入库单明细不能为空');
    }
    
    // 确认入库单并更新库存
    await prisma.$transaction(async (prisma) => {
      // 更新入库单状态
      await prisma.stockInOrder.update({
        where: { id: parseInt(id) },
        data: { status: 1 } // 已确认状态
      });
      
      // 更新商品库存
      for (const item of stockInOrder.items) {
        // 查询商品当前库存
        const product = await prisma.product.findUnique({
          where: { id: item.productId }
        });
        
        if (!product) {
          throw new ApiError(404, `商品ID:${item.productId}不存在`);
        }
        
        // 更新商品库存
        const currentStock = parseFloat(product.stockQuantity || 0);
        const newStock = currentStock + parseFloat(item.quantity);
        
        await prisma.product.update({
          where: { id: item.productId },
          data: { 
            stockQuantity: newStock,
            stockUnit: item.unit || product.stockUnit,
            costPrice: parseFloat(item.costPrice) || product.costPrice, // 更新成本价
            stockStatus: getStockStatus(newStock, product.minimumStock, product.maximumStock)
          }
        });
        
        // 创建库存记录
        await prisma.inventoryRecord.create({
          data: {
            productId: item.productId,
            warehouseId: stockInOrder.warehouseId,
            quantity: parseFloat(item.quantity),
            unit: item.unit,
            batchNumber: item.batchNumber,
            productionDate: item.productionDate,
            expiryDate: item.expiryDate,
            costPrice: parseFloat(item.costPrice)
          }
        });
        
        // 记录库存变动
        await prisma.stockMovement.create({
          data: {
            productId: item.productId,
            warehouseId: stockInOrder.warehouseId,
            movementType: 1, // 入库
            quantity: parseFloat(item.quantity),
            beforeQuantity: currentStock,
            afterQuantity: newStock,
            relatedOrderType: 'StockInOrder',
            relatedOrderId: stockInOrder.id,
            operatorId: req.user.id,
            remarks: `入库单${stockInOrder.orderNumber}入库`
          }
        });
      }
    });
    
    res.json({
      success: true,
      message: '入库单确认成功'
    });
  } catch (error) {
    next(error);
  }
};

/**
 * 取消入库单
 */
exports.cancelStockInOrder = async (req, res, next) => {
  try {
    const { id } = req.params;
    
    // 查询入库单
    const stockInOrder = await prisma.stockInOrder.findUnique({
      where: { id: parseInt(id) }
    });
    
    if (!stockInOrder) {
      throw new ApiError(404, '入库单不存在');
    }
    
    // 只有草稿状态的入库单可以取消
    if (stockInOrder.status !== 0) {
      throw new ApiError(400, '只有草稿状态的入库单可以取消');
    }
    
    // 更新入库单状态
    await prisma.stockInOrder.update({
      where: { id: parseInt(id) },
      data: { status: 2 } // 已取消状态
    });
    
    res.json({
      success: true,
      message: '入库单已取消'
    });
  } catch (error) {
    next(error);
  }
};

/**
 * 根据库存数量和预警阈值获取库存状态
 * @param {Number} quantity 库存数量
 * @param {Number} minimumStock 最低库存
 * @param {Number} maximumStock 最高库存
 * @returns {Number} 库存状态 0: 缺货, 1: 正常, 2: 预警, 3: 超储
 */
function getStockStatus(quantity, minimumStock, maximumStock) {
  if (quantity <= 0) {
    return 0; // 缺货
  }
  
  if (minimumStock && quantity < minimumStock) {
    return 2; // 预警
  }
  
  if (maximumStock && quantity > maximumStock) {
    return 3; // 超储
  }
  
  return 1; // 正常
}

/**
 * 添加入库单明细
 */
exports.addStockInItem = async (req, res, next) => {
  try {
    const { id } = req.params;
    const { productId, quantity, unit, costPrice, batchNumber, productionDate, expiryDate, remarks } = req.body;
    
    // 验证必要字段
    if (!productId || !quantity) {
      throw new ApiError(400, '商品和数量不能为空');
    }
    
    // 查询入库单
    const stockInOrder = await prisma.stockInOrder.findUnique({
      where: { id: parseInt(id) }
    });
    
    if (!stockInOrder) {
      throw new ApiError(404, '入库单不存在');
    }
    
    // 只有草稿状态的入库单可以添加明细
    if (stockInOrder.status !== 0) {
      throw new ApiError(400, '只有草稿状态的入库单可以修改');
    }
    
    // 检查商品是否存在
    const product = await prisma.product.findUnique({
      where: { id: parseInt(productId) }
    });
    
    if (!product) {
      throw new ApiError(404, '商品不存在');
    }
    
    // 计算总价
    const totalPrice = parseFloat(quantity) * (parseFloat(costPrice) || 0);
    
    // 创建入库单明细
    const stockInItem = await prisma.stockInItem.create({
      data: {
        stockInId: parseInt(id),
        productId: parseInt(productId),
        quantity: parseFloat(quantity),
        unit: unit || product.stockUnit,
        costPrice: costPrice ? parseFloat(costPrice) : null,
        totalPrice,
        batchNumber,
        productionDate: productionDate ? new Date(productionDate) : null,
        expiryDate: expiryDate ? new Date(expiryDate) : null,
        remarks
      }
    });
    
    // 更新入库单总金额
    const items = await prisma.stockInItem.findMany({
      where: { stockInId: parseInt(id) }
    });
    
    const totalAmount = items.reduce((sum, item) => {
      return sum + (item.totalPrice || 0);
    }, 0);
    
    await prisma.stockInOrder.update({
      where: { id: parseInt(id) },
      data: { totalAmount }
    });
    
    res.status(201).json({
      success: true,
      data: stockInItem,
      message: '入库单明细添加成功'
    });
  } catch (error) {
    next(error);
  }
};

/**
 * 更新入库单明细
 */
exports.updateStockInItem = async (req, res, next) => {
  try {
    const { id, itemId } = req.params;
    const { quantity, unit, costPrice, batchNumber, productionDate, expiryDate, remarks } = req.body;
    
    // 查询入库单
    const stockInOrder = await prisma.stockInOrder.findUnique({
      where: { id: parseInt(id) }
    });
    
    if (!stockInOrder) {
      throw new ApiError(404, '入库单不存在');
    }
    
    // 只有草稿状态的入库单可以修改明细
    if (stockInOrder.status !== 0) {
      throw new ApiError(400, '只有草稿状态的入库单可以修改');
    }
    
    // 查询入库单明细
    const stockInItem = await prisma.stockInItem.findUnique({
      where: { id: parseInt(itemId) }
    });
    
    if (!stockInItem || stockInItem.stockInId !== parseInt(id)) {
      throw new ApiError(404, '入库单明细不存在');
    }
    
    // 计算总价
    const totalPrice = parseFloat(quantity || stockInItem.quantity) * 
                      (parseFloat(costPrice || stockInItem.costPrice) || 0);
    
    // 更新入库单明细
    const updatedStockInItem = await prisma.stockInItem.update({
      where: { id: parseInt(itemId) },
      data: {
        quantity: quantity ? parseFloat(quantity) : undefined,
        unit,
        costPrice: costPrice ? parseFloat(costPrice) : undefined,
        totalPrice,
        batchNumber,
        productionDate: productionDate ? new Date(productionDate) : undefined,
        expiryDate: expiryDate ? new Date(expiryDate) : undefined,
        remarks
      }
    });
    
    // 更新入库单总金额
    const items = await prisma.stockInItem.findMany({
      where: { stockInId: parseInt(id) }
    });
    
    const totalAmount = items.reduce((sum, item) => {
      return sum + (item.totalPrice || 0);
    }, 0);
    
    await prisma.stockInOrder.update({
      where: { id: parseInt(id) },
      data: { totalAmount }
    });
    
    res.json({
      success: true,
      data: updatedStockInItem,
      message: '入库单明细更新成功'
    });
  } catch (error) {
    next(error);
  }
};

/**
 * 删除入库单明细
 */
exports.deleteStockInItem = async (req, res, next) => {
  try {
    const { id, itemId } = req.params;
    
    // 查询入库单
    const stockInOrder = await prisma.stockInOrder.findUnique({
      where: { id: parseInt(id) }
    });
    
    if (!stockInOrder) {
      throw new ApiError(404, '入库单不存在');
    }
    
    // 只有草稿状态的入库单可以删除明细
    if (stockInOrder.status !== 0) {
      throw new ApiError(400, '只有草稿状态的入库单可以修改');
    }
    
    // 查询入库单明细
    const stockInItem = await prisma.stockInItem.findUnique({
      where: { id: parseInt(itemId) }
    });
    
    if (!stockInItem || stockInItem.stockInId !== parseInt(id)) {
      throw new ApiError(404, '入库单明细不存在');
    }
    
    // 删除入库单明细
    await prisma.stockInItem.delete({
      where: { id: parseInt(itemId) }
    });
    
    // 更新入库单总金额
    const items = await prisma.stockInItem.findMany({
      where: { stockInId: parseInt(id) }
    });
    
    const totalAmount = items.reduce((sum, item) => {
      return sum + (item.totalPrice || 0);
    }, 0);
    
    await prisma.stockInOrder.update({
      where: { id: parseInt(id) },
      data: { totalAmount }
    });
    
    res.json({
      success: true,
      message: '入库单明细删除成功'
    });
  } catch (error) {
    next(error);
  }
}; 